Devel::Cover and Self-Modifying Code; OR Doctor! Doctor!

Mark Leighton Fisher on 2005-01-08T12:46:05

"Doctor! Doctor! I just broke my arm in 17 places!"
"Well, for goodness sakes don't GO in those places, then!"
(thereby finishing the introductory joke).

I've been writing some code for a client's application that deals with sensitive data -- sensitive enough that I wanted to avoid printing out the data EXCEPT during testing. Looking through CPAN, I thought "Aha! Devel::StealthDebug looks like just the ticket! I can print out the sensitive data during testing, then I can comment-out the code in production so there won't even be a trace of the print statement."

Looking back, I'd just as soon start dereferencing NULL pointers in C as do what I did. Turns out that Devel::Cover will silently refuse to output any coverage data if you modify your code after you have started testing. (I had used a kludge of writing fake tests to turn on and turn off the load of Devel::StealthDebug by modifying the code of the module I was testing.)

The workaround?

  1. Write a tiny module that exported upon request a function stealth_print() to do the testing printing for me.
  2. Have the fake tests turn testing printing on and off by modifying the code of this separate module.

Why, you might ask (or you might not -- I don't know you) didn't I continue to use Devel::StealthDebug? Because it is currently implemented as a source filter, which (I think) means that it has to be loaded by the module that is directly using it in order to work. Moving the load of Devel::StealthDebug to a separate module means that the separate module can use Devel::StealthDebug's printing facilities, but the main module cannot use Devel::StealthDebug's facilities anymore.

(Just as a point of interest, I have been programming in Perl for 12 years now but this is my first self-modifying code.)